package com.wander.concurrent;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.TimeUnit;

public class ThreadWaitNotifyExample {
    private static final int MAX_SIZE = 5;
    private static final int hello = 0;
    private final Queue<Integer> queue = new LinkedList();

    public static void main(String[] args) {
        ThreadWaitNotifyExample example = new ThreadWaitNotifyExample();
        Thread thread1 = new Thread(example::produce);
        Thread thread2 = new Thread(example::consume);
        Thread thread3 = new Thread(example::produce);
        thread1.start();
        thread2.start();
//        thread3.start();

    }

    public void produce(){
        int value = 0;
        while (true) {
            synchronized (queue) {
                while (queue.size() == MAX_SIZE) {
                    try {
                        System.out.println("队列已满，生产者等待...");
                        queue.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("生产数据：" + value);
                queue.add(value++);
                queue.notify();//唤醒消费者
            }
            try {
                //模拟生产耗时
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }


    //消费者方法
    public void consume(){
        while (true) {
            synchronized (queue) {
                while (queue.size() == 0) {
                    try {
                        System.out.println("队列为空，消费者等待...");
                        queue.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                int value = queue.poll();
                System.out.println("消费数据：" + value);
//                queue.notifyAll();
            }
            try {
                TimeUnit.MILLISECONDS.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
